package org.uned.agonzalo16.bitacora.web.user;

import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.validation.Valid;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.uned.agonzalo16.bitacora.dao.UserDao;
import org.uned.agonzalo16.bitacora.domain.User;

@RequestMapping("/admin/user")
@Controller
public class AdminUserController {

	private static final Logger logger = Logger.getLogger(AdminUserController.class);

	@Autowired
	private UserDao userDao;

	@Autowired
	private ChangePasswordValidator changePasswordValidator;

	@Autowired
	private UserValidator userValidator;

	@RequestMapping(method = RequestMethod.GET, value = "/list")
	public String list(Model model) {
		List<User> users = userDao.findAll();
		Collections.sort(users, new Comparator<User>() {
			@Override
			public int compare(User u1, User u2) {
				return u1.getUsername().compareToIgnoreCase(u2.getUsername());
			}
		});
		model.addAttribute("users", users);
		return "user/list";
	}

	@RequestMapping(method = RequestMethod.GET, value = "/beginCreate")
	public String beginCreate(Model model) {
		model.addAttribute("user", new UserForm());
		return "user/create";
	}

	@RequestMapping(method = RequestMethod.POST, value = "/create")
	public String create(@Valid @ModelAttribute("user") UserForm form, BindingResult result) {

		logger.debug("Start creating user...");

		userValidator.validate(form, result);

		if (result.hasErrors()) {
			return "user/create";
		}

		User user = new User();
		user.setActive(true);
		user.setCreationDate(new Date());
		user.setEmail(form.getEmail());
		user.setLocalization(form.getLocalization());
		user.setPassword(form.getPassword());
		user.setType(form.getType());
		user.setUsername(form.getUsername());
		user.setWebSite(form.getWebSite());

		userDao.merge(user);

		logger.debug("User created with id " + user.getId());

		return "redirect:/admin/user/list";
	}

	@RequestMapping(method = RequestMethod.GET, value = "/show/{id}")
	public String show(@PathVariable("id") Long id, Model model) {
		model.addAttribute("user", new UserForm(userDao.get(id)));
		return "user/update";
	}

	@RequestMapping(method = RequestMethod.POST, value = "/update")
	public String update(@Valid @ModelAttribute("user") UserForm form, BindingResult result) {

		logger.debug("Start updating user...");

		userValidator.validate(form, result);

		if (result.hasErrors()) {
			return "user/update";
		}

		User user = userDao.get(form.getId());
		user.setEmail(form.getEmail());
		user.setLocalization(form.getLocalization());
		user.setUsername(form.getUsername());
		user.setWebSite(form.getWebSite());

		userDao.merge(user);

		logger.debug("User updated with id " + user.getId());

		return "redirect:/admin/user/list";
	}

	@RequestMapping(method = RequestMethod.GET, value = "/activate/{id}")
	public String activate(@PathVariable("id") Long id) {
		User user = userDao.get(id);
		user.setActive(true);
		userDao.merge(user);
		return "redirect:/admin/user/show/" + id;
	}

	@RequestMapping(method = RequestMethod.GET, value = "/desactivate/{id}")
	public String desactivate(@PathVariable("id") Long id) {
		User user = userDao.get(id);
		user.setActive(false);
		userDao.merge(user);
		return "redirect:/admin/user/show/" + id;
	}

	@RequestMapping(method = RequestMethod.GET, value = "/pass/{id}")
	public String pass(@PathVariable("id") Long id, Model model) {
		model.addAttribute("passForm", new ChangePasswordForm(userDao.get(id)));
		return "user/pass";
	}

	@RequestMapping(method = RequestMethod.POST, value = "/changePass")
	public String changePass(@Valid @ModelAttribute("passForm") ChangePasswordForm form, BindingResult result) {

		logger.debug("Start updating user password...");

		changePasswordValidator.validate(form, result);

		if (result.hasErrors()) {
			return "user/pass";
		}

		User user = userDao.get(form.getId());
		user.setPassword(form.getNewPassword());

		userDao.merge(user);

		logger.debug("User password updated with id " + user.getId());

		return "redirect:/admin/user/show/" + form.getId();
	}

}
